# -*- coding: utf-8 -*-  

import sys
import os
import xlrd
# xlrd 1.2.0后面得版本取消了对xlsx文件得读取，因此安装命令应为：pip install xlrd==1.2.0
from XlsxHelper import XlsxHelper
from tqdm import tqdm
# xlwings，比xlsxwriter快10倍，但是需要win32api，教程：https://zhuanlan.zhihu.com/p/54003662

class XlsxContrast:
    '''Xlsx对比工具类'''
    __default_config = {
                "leftTableFile":"testData.xls",
                "rightTableFile":"testData.xls",
                "contrastColumns":"B,C,D",
                "outputFileName":"contrast_testData-testData.xls",
                "operationMode":"1" # 1:找相同（可以对同一个表操作）2：找出左表有右表无的数据行
            }

    def __init__(self,skip_input_config:bool=False,config:dict=None):
        '''创建对比工具实例（是否直接使用配置文件执行，配置文件)'''
        self.skip_input_config = skip_input_config
        if config is None:
            self.config = {}
        else:
            self.config = config
            self.__default_config = config
    
    def setting_menu(self):
        '''输入配置信息'''
        print("在执行Xlsx文件“对比”之前需要做以下配置，使用默认值请直接回车。")
        leftTableFile=self.__input("leftTableFile","要对比的文件")
        rightTableFile=self.__input("rightTableFile","另一个要对比的文件，可以是同一个文件",leftTableFile)
        contrastColumns=self.__input("contrastColumns","要对比的列号，用英文逗号“,”分隔")
        outputFileName=self.__input("outputFileName","输出文件的文件名")
        operationMode=self.__input("operationMode",'''
        选择程序运行方式：
        1：找相同（可以对同一个表操作）
        2：找出左表有右表无的数据行
        ''')

        config_item = {
            "leftTableFile":leftTableFile,
            "rightTableFile":rightTableFile,
            "contrastColumns":contrastColumns,
            "outputFileName":outputFileName,
            "operationMode":operationMode
        }
        self.config=config_item
        # end while
            
    def __input(self,config_key:str,input_title:str,default_value:str = None):
        '''显示输入配置的操作(配置的键，显示的提示)'''
        originalValue = self.__default_config[config_key] if default_value is None else default_value
        inputText = input(f"请输入，{input_title}（默认值：{originalValue}）：")
        newVal = inputText if inputText!="" else originalValue
        return newVal

    def str_to_intArr(self,contrastColumnstr:str):
        ccStrArr = contrastColumnstr.split(",")
        ccintArr = [ord(item)-65 for item in ccStrArr]
        return ccintArr

    def load_xlsx(self,filename,contrastColumnImdexs):
        result = []
        wb = xlrd.open_workbook(filename)
        # 输出全部表
        sheet = wb.sheets()[0]
        resultData = []
        featureData = []
        print(f"正在加载文件：{filename}")
        for rownum in tqdm(range(sheet.nrows)):
            rowData = sheet.row_values(rownum)
            features = ""            
            for col in contrastColumnImdexs:
                features += f",{rowData[col]}"
            featureData.append(features)
            resultData.append(rowData)
        return resultData,featureData

    def contrast(self,searchNotIn:bool = False):
        '''执行对比(是否查找重复，是：以左表为准找右表缺失，否：在左右两表中找相同行)'''
        if self.skip_input_config == False:
            self.setting_menu()
            searchNotIn = self.config["operationMode"] != "1"
                
        xlsx_helper = XlsxHelper()
        contrastColumnImdexs = self.str_to_intArr(self.config["contrastColumns"])
        leftTableFile = self.config["leftTableFile"]
        rightTableFile = self.config["rightTableFile"]
        leftData,leftFeature = self.load_xlsx(leftTableFile,contrastColumnImdexs)
        # 是否是与自身对比
        isSelfContrast = leftTableFile == rightTableFile
        if isSelfContrast:
            rightData = leftData
            rightFeature = leftFeature
        else:
            rightData,rightFeature = self.load_xlsx(rightTableFile,contrastColumnImdexs)

        def judge_same():
            '''查找相同'''
            sameData = []
            for i in tqdm(range(len(leftFeature))):
                if leftFeature[i] in rightFeature:
                    j = rightFeature.index(leftFeature[i])
                    if all([isSelfContrast,i==j]):
                        continue
                    else:
                        sameRow = leftData[i][:]
                        sameRow.append(f"{leftTableFile}[row:{i}] <--> {rightTableFile}[row:{j}]")
                        sameData.append(sameRow)
            return sameData
        def judge_searchNotIn():
            '''查找左表有右表没有的'''
            resultData = []
            for i in tqdm(range(len(leftFeature))):
                if leftFeature[i] not in rightFeature:
                    row = leftData[i][:]
                    row.append(f"{leftTableFile}[row:{i}] <--> {rightTableFile}[row:None]")
                    resultData.append(row)
            return resultData
        print("正在对比...")
        result =  judge_searchNotIn() if searchNotIn else judge_same()
        xlsx_helper.save_to_new_file(self.config["outputFileName"],result)
        print("完成")

if __name__=="__main__":
    '''测试xlsx数据对比'''
    # 无参
    if len(sys.argv)==1:
        xc = XlsxContrast()
        xc.contrast() 
    elif all([len(sys.argv)==2,sys.argv[1]=="--help"]):
        print(r'''
对比工具：XlsxContrast.py
命令行参数：
py XlsxContrast.py [--help][-same|-different][-l fileName0.xls][-r fileName1.xls][-o outputFile.xls][-c B,C,D]

--help              显示当前帮助		
-same               筛选相同的行(与 -different 不能同时使用)
-different          筛选不同的行(与 -same 不能同时使用)
-l fileName0.xls    左表的文件路径
-r fileName1.xls    右表的文件路径，与左表一致表示对自身进行对比
-o outputFile.xls   输出结果的文件路径
-c B,C,D            参与对比的列名

示例1：对比自身，找出相同行：
py .\XlsxContrast.py -same -l .\testData.xls -r .\testData.xls -o .\output-same.xls -c B,C,D

示例2：对比左右两表，以左表为准，找出右表缺失的行：
py .\XlsxContrast.py -different -l .\testData.xls -r .\testData2.xls -o .\output-different.xls -c B,C,D

输出文件说明，文件会复制左表整行，并在最右边插入一列，内容如下：

找相同：
.\testData.xls[row:6312] <--> .\testData.xls[row:1648]
左表文件之6312行，与右表文件之1648行相同

找不同
.\testData.xls[row:16] <--> .\testData2.xls[row:None]
左表文件之16行，在右表中找不到相同的行
        ''')
    else:
        config = {}
        args = {
            "-l":"leftTableFile",
            "-r":"rightTableFile",
            "-c":"contrastColumns",
            "-o":"outputFileName"
        }
        for i in range(1,len(sys.argv)-1):
            if sys.argv[i] in args.keys():
                config[args[sys.argv[i]]] = sys.argv[i+1]
                continue
            if sys.argv[i]=="-same":
                config["operationMode"] = 1
                continue
            if sys.argv[i]=="-different":
                config["operationMode"] = 2
                continue
        xc = XlsxContrast(True,config)
        xc.contrast(config["operationMode"]!=1) 
